package net.buffer;

import net.buffer.ByteBuffer;

import java.io.IOException;
import java.io.InputStream;
import java.util.function.Consumer;

public class IntPack {

    private final ByteBuffer buffer;
    private Consumer<ByteBuffer> handler;
    private ByteBuffer last;
    private final ByteBuffer lenBuffer;

    public IntPack(int capacity)
    {
        buffer = new ByteBuffer(capacity);
        lenBuffer = new ByteBuffer(4);
    }

    public int unpack(InputStream in) throws IOException {

        int readCount = buffer.put(in);
        if(readCount > 0)
        {
            read(buffer);
        }else if(readCount == 0)
        {
        }
        return readCount;
    }

    private void read(ByteBuffer buffer)
    {
        buffer.read();
//        System.out.println("read "+ buffer);
        while (buffer.remaining() > 0)
        {
            if(last == null)
            {
                lenBuffer.fill(buffer);
                if(lenBuffer.remaining() == 0)
                {
                    int len = lenBuffer.read().getInt();
                    last = new ByteBuffer(len);
//                    System.out.println("create "+len);
                }
                else if (lenBuffer.remaining() < 0)
                {
                    throw new RuntimeException("lenBuffer.remaining() < 0 isn't enable!");
                }
            }
            last.fill(buffer);
//            System.out.println("last "+ last + " reaming "+ last.remaining());
            if(last.remaining() == 0)
            {
//                System.out.println(" pack  complete");
                this.handler.accept(last);
                last = null;
                lenBuffer.clear();
            } else if (last.remaining() < 0) {
                throw new RuntimeException("last.remaining() < 0 isn't enable!");
            }
        }
        buffer.clear();
    }

    public static ByteBuffer pack(ByteBuffer data)
    {
        int len = data.remaining();
        ByteBuffer buf = new ByteBuffer(len+4);
        buf.putInt(len);
        buf.fill(data);
        return buf;
    }


    public void setPackHandler(Consumer<ByteBuffer> handler)
    {
        this.handler = handler;
    }

}
